package cn.hy.guava.bus;


import com.google.common.eventbus.AsyncEventBus;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.SubscriberExceptionContext;
import com.google.common.eventbus.SubscriberExceptionHandler;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.PostConstruct;
import java.util.List;
import java.util.concurrent.Executors;

@Component
public class EventBusCenter {

    private ThreadLocal<RuntimeException> threadLocal = new ThreadLocal();

    // 同步
    private EventBus eventBus = new EventBus(new SubscriberExceptionHandler() {
        // 同步调用过程中 客户端如何获取异常
        @Override
        public void handleException(Throwable exception, SubscriberExceptionContext context) {
            if (exception instanceof RuntimeException) {
                threadLocal.set((RuntimeException) exception);
            }

        }
    });

    private EventBus asyncEventBus = new AsyncEventBus(Executors.newSingleThreadExecutor());


    public void postSync(Object event) {
        eventBus.post(event);
        RuntimeException ex = threadLocal.get();
        if (ex != null) {
            // 记得 remove
            threadLocal.remove();
            throw ex;
        }
    }

    public void postAsync(Object event) {
        asyncEventBus.post(event);
    }



    @PostConstruct
    public void initRegistryBean() {
        List<Object> beansWithAnnotation = SpringContextUtils.getBeansWithAnnotation(EventBusListener.class);
        if(!CollectionUtils.isEmpty(beansWithAnnotation)) {
            beansWithAnnotation.forEach(bean -> eventBus.register(bean));
            // beansWithAnnotation.forEach(bean -> asyncEventBus.register(bean));
        }
    }


}
